/* ------------------------------------------------------------------------*
 *
 * ------------------------------------------------------------------------*/
#include "stdint.h"
#include "os_obj.h"
#include "bsp.h"

#include "nor_cmd.h"
#include "bsp_spi_nor.h"
#include "simp_log2_ext.h"

#include "str_ext.h"
#include "common.h"
/*****************************************************************************
 * @brief   delay .
 *****************************************************************************/

static void LogErase(uint32_t AddrBase);							 /*从指定地址擦除，Nums指定擦除的扇区个数*/
static void LogProgram(uint32_t Addr, uint32_t *Data, uint16_t Len); /*向指定指定地址编程数据*/
static void LogRead(uint32_t Addr, uint32_t *Data, uint16_t Len);	 /*读取块数据*/
int32_t log2_iter_back(int32_t site, uint8_t *dat);

// 日志数据
typedef struct
{
	sig_time_type time;
	uint16_t temp_pv;
	uint16_t temp_sv;
	uint16_t humi_pv;
	uint16_t humi_sv;
	uint16_t ver[24];
} log_dat_type;

static log_dat_type log_dat;

// 日志配置
simp_log2_ext_api_ref(log2_cfg);
simp_log2_info_type log2_info;

simp_log2_type log2_cfg = {
	.addr_base = 384 * 1024,
	.total_size = 128 * 1024,
	.page_size = 4 * 1024,
	.dat_size = 32,
	.info = &log2_info,
	.Erase = LogErase,
	.Program = LogProgram,
	.Read = LogRead,
	.api = simp_log2_api_name(log2_cfg)};

simp_log2_ext_api_make(log2_cfg);

// 日志缓存管理
typedef struct
{
	int32_t search_res;
	sig_time_type sig_time;
	TIME_Type rtc_time;
	log_dat_type log_rd;
	uint16_t save_req;
	uint16_t read_req;
	uint8_t clr_req;
	uint8_t alain_req;
	int8_t tm_search_req;
	uint8_t hd_search_req;
	uint8_t init_req;
	uint32_t start_addr;
	uint32_t next_addr;
	uint32_t res_addr;
} log_buff_test_type;

log_buff_test_type simp_log_obj;

/*******************************************************************************
 * @brief: 初始化
 * @param cfg
 * @return {*}
 ******************************************************************************/
void log2_auto_init(void)
{
	log2_cfg.api->init();
}
obj_init_order5(log2_auto_init);

/*******************************************************************************
 * @brief: 初始化
 * @param cfg
 * @return {*}
 ******************************************************************************/
int log2_init(int argc, char **argv)
{
	log2_cfg.api->init();

	dbg_print("log info: start %d, next: %d" PTCR, log2_cfg.info->site_start, log2_cfg.info->site_next);

	return 0;
}
DBG_FUN_EXPORT(log2_init);

/*******************************************************************************
 * @brief: 清除
 * @param cfg
 * @return {*}
 ******************************************************************************/
int log2_clr(int argc, char **argv)
{
	loop(log2_cfg.total_size / log2_cfg.page_size)
	{
		LogErase(log2_cfg.addr_base + index * log2_cfg.page_size);
	}

	log2_cfg.api->init();
	simp_log_obj.clr_req = 0;

	return 0;
}
DBG_FUN_EXPORT(log2_clr);

/*******************************************************************************
 * @brief: 存储
 * @param cfg
 * @return {*}
 ******************************************************************************/
int log2_save(int argc, char **argv)
{
	int cnt = 1, tim = 1;

	if (argc > 1)
		cnt = atoi(argv[1]);

	if (argc > 2)
		tim = atoi(argv[2]);

	// 保存日志
	while (cnt--)
	{
		log_dat.time.val = tim;
		log_dat.temp_pv = (log_dat.temp_pv + 3) & 0x7FF;
		log_dat.humi_pv = (log_dat.humi_pv + 5) & 0x3FF;
		log2_cfg.api->save(&log_dat);
		tim++;
	}

	dbg_puts("save end" PTCR);
	dbg_puts(SYMBOL_LINE_EQ PTCR);

	return 0;
}
DBG_FUN_EXPORT(log2_save);

/*******************************************************************************
 * @brief: 存储
 * @param cfg
 * @return {*}
 ******************************************************************************/
int log2_siter(int argc, char **argv)
{
	int s = 1, e = 1;

	if (argc > 1)
		s = atoi(argv[1]);

	if (argc > 2)
		e = atoi(argv[2]);

	// 保存日志
	simp_log2_site_iter(&log2_cfg, s, e, log2_iter_back);

	dbg_puts(SYMBOL_LINE_EQ PTCR);

	return 0;
}
DBG_FUN_EXPORT(log2_siter);

int log2_titer(int argc, char **argv)
{
	int s = 1, e = 1;

	if (argc > 1)
		s = atoi(argv[1]);

	if (argc > 2)
		e = atoi(argv[2]);

	// 保存日志
	simp_log2_time_iter(&log2_cfg, s, e, log2_iter_back);

	dbg_puts(SYMBOL_LINE_EQ PTCR);

	return 0;
}
DBG_FUN_EXPORT(log2_titer);

int log2e_siter(int argc, char **argv)
{
	int s = 1, e = 1;

	if (argc > 1)
		s = atoi(argv[1]);

	if (argc > 2)
		e = atoi(argv[2]);

	// 保存日志
	log2_cfg.api->site_iter(s, e, log2_iter_back);

	dbg_puts(SYMBOL_LINE_EQ PTCR);

	return 0;
}
DBG_FUN_EXPORT(log2e_siter);

int log2e_titer(int argc, char **argv)
{
	int s = 1, e = 1;

	if (argc > 1)
		s = atoi(argv[1]);

	if (argc > 2)
		e = atoi(argv[2]);

	// 保存日志
	log2_cfg.api->time_iter(s, e, log2_iter_back);

	dbg_puts(SYMBOL_LINE_EQ PTCR);

	return 0;
}
DBG_FUN_EXPORT(log2e_titer);

int32_t log2_iter_back(int32_t site, uint8_t *dat)
{
	log_dat_type *ld;

	ld = (log_dat_type *)dat;

	dbg_print("site:%6d, tim:%8d, temp:%d, humi:%d" PTCR, site, ld->time.val, ld->temp_pv, ld->humi_pv);

	return 1;
}

/*--------------------------------------------------------------------------------*
 * log buff hal
 *---------------------------------------------------------------------------------*/
void LogProgram(uint32_t Addr, uint32_t *Data, uint16_t Len)
{
	nor_write_multi(Addr, Len, (uu8 *)Data);
}

void LogRead(uint32_t Addr, uint32_t *Data, uint16_t Len)
{
	nor_read(Addr, Len, (uu8 *)Data);
}

void LogErase(uint32_t AddrBase)
{
	nor_sector_erase(AddrBase);
}
